CA327 Object-oriented Programming using Java Question Bank Solutions


Q1. Why are Java programs platform-independent?

Answer

Java programs are platform-independent because of their "Write Once, Run Anywhere" (WORA) nature. This works through a two-step process:

  1. Compilation to Bytecode: Instead of compiling directly to machine code, the Java compiler turns your .java source code into an intermediate format called bytecode (.class file). This bytecode is universal and not tied to any platform.
  2. Execution by JVM: To run the program, you need a Java Virtual Machine (JVM). The JVM acts as a translator that takes the universal bytecode and executes it on the specific hardware and operating system.

Since there's a specific JVM for Windows, another for macOS, and another for Linux, the same universal bytecode file can be executed on any of them.

Funny Example 🤣

Think of Java bytecode as an IKEA instruction manual. It's just pictures, no words, so anyone from any country (any OS) can understand it. The JVM is like a person from that country who looks at the pictures and says, "Ah, okay, so I need to use this specific Allen key and this screw," using the tools (machine code) available in their own home (their OS) to build the exact same bookshelf.

Mermaid Diagram

☕ Java Compiler

📜 Universal Bytecode (.class)

📄 Source Code (.java)

🖥️ JVM for Windows

🍎 JVM for macOS

🐧 JVM for Linux

✅ Same Program Output


Q2. Draw a diagram illustrating Java program compilation and execution.

Answer

The compilation and execution of a Java program follows a clear, structured flow from source code to final output.

Step-by-Step Flow:

  1. Source Code (.java file): The developer writes the program.
  2. Java Compiler (javac.exe): The source code is compiled.
  3. Bytecode (.class file): The compiler produces a platform-independent bytecode file.
  4. Java Virtual Machine (JVM): This bytecode is loaded into the JVM, which is launched by the java command.
  5. Interpreter & JIT Compiler: Inside the JVM, the bytecode is converted into native machine code and stored in memory.
  6. CPU Execution: The computer's processor runs this native code.
  7. Output: The program's result is displayed.
Funny Example: Baking a Cake 🎂
  1. .java file: Your unique, handwritten cake recipe.
  2. javac compiler: A kitchen robot that scans your recipe and prints it in a standard, universal format that any baker can read.
  3. .class file: The standardized recipe printout.
  4. JVM: A master baker who takes the standard recipe.
  5. Machine Code: The baker translates the recipe into actual actions—cracking eggs, mixing flour, etc.
  6. CPU: The oven that bakes the cake.
  7. Output: A delicious cake!
Mermaid Diagram

The User's Computer

You The Programmer

📝 Source Code (.java)

🔨 Compiler (javac)

📜 Bytecode (.class)

⚙️ JVM

🏃‍♂️ Interpreter + JIT

🧠 Machine Code

💻 CPU

🎉 Output


Q3. Explain Just-In-Time compilation.

Answer

The Just-In-Time (JIT) compiler is a component of the JVM that makes Java programs run faster.

Instead of interpreting the same piece of code over and over, the JIT compiler identifies "hot code"—parts of the program that are executed frequently, like the body of a loop. It then compiles that specific part directly into fast, native machine code and saves it in memory.

The next time the program needs to run that "hot" section, it uses the already-compiled native code, which is much faster than interpreting the bytecode again. Less-used "cold code" is still interpreted normally. This provides a major performance boost for the application.

Funny Example: The Shortcut King 👑

Imagine you're giving a tour of your city (running a program). At first, you follow the map for every route (interpreting). But you quickly notice that every single tourist wants to go from the Hotel to the Big Pizza Place (hot code).

Instead of looking at the map every time, you memorize the fastest shortcut (JIT compilation). Now, whenever someone asks for the Big Pizza Place, you take the lightning-fast shortcut from memory, saving a ton of time. For all the other rare destinations, you still use the map.

Mermaid Diagram

Yes (It's Hot!)

No (It's Cold)

Bytecode

Is this code used a lot?

🔥 JIT Compiler

🚀 Super-Fast Native Code

🐌 Interpreter

🐢 Normal Native Code

⚡ Execute on CPU


Q4. Explain why Java programs are considered as secured.

Answer

Java has several built-in features that make it a secure programming language:

  • No User-Defined Pointers: Java doesn't allow programmers to directly access memory locations. This prevents a major category of attacks where malicious code could otherwise read or corrupt memory.
  • Sandbox Model: The JVM runs Java code in a restricted environment called a "sandbox." This is like a digital playpen that prevents the code from accessing sensitive parts of your system, like local files, without permission.
  • Bytecode Verifier: Before running any code, the JVM uses a verifier to check the bytecode for illegal operations, like violating access rights. This acts as a security guard, ensuring the code plays by the rules.
  • Automatic Garbage Collection: Java automatically handles memory deallocation. This prevents common vulnerabilities like memory leaks and buffer overflows that can be exploited in other languages.
Funny Example: The Bouncy Castle 🏰

Running a Java program is like putting it inside a giant, secure bouncy castle (Sandbox).

  • There are no sharp objects inside (No Pointers).
  • A security guard (Bytecode Verifier) checks everyone at the entrance to make sure they won't cause trouble.
  • A dedicated cleaning crew (Garbage Collector) instantly removes any toys that are no longer being played with, so nobody trips over them.
    The program can have a lot of fun inside, but it can't damage the outside world (your computer).
Mermaid Diagram
🛡️ Java SecuritySandbox ModelNo PointersBytecode VerifierGarbage CollectionIsolates codePrevents memorytamperingChecks code before it runsManages memoryautomatically

Q5. Discuss multithreading capability of Java programs.

Answer

Multithreading is a powerful Java feature that allows a program to do multiple things at the same time by executing different parts of its code concurrently. Each of these concurrent execution paths is called a thread.

  • Concurrent Execution: A single Java program can have many threads running simultaneously. For example, one thread could be downloading a file from the internet while another thread updates a progress bar on the screen.
  • Improved Performance: By breaking down a large task into smaller sub-tasks and running them in parallel on different threads, programs can make better use of the computer's CPU and finish their work much faster.
  • Enhanced Responsiveness: Multithreading is key to creating responsive applications. In a desktop app, if a time-consuming task runs on a separate thread, the main user interface thread remains free to respond to user actions like button clicks, preventing the application from "freezing".
Funny Example: The Super-Efficient Restaurant 🍔

A single-threaded program is like a restaurant with only one worker who does everything: takes the order, cooks the food, serves it, and then handles the bill. It's incredibly slow.

A multi-threaded program is a modern restaurant:

  • Thread 1 (Waiter): Takes your order.
  • Thread 2 (Chef): Cooks the food.
  • Thread 3 (Busboy): Fills your water glass.
  • Thread 4 (Cashier): Prepares the bill.
    All these tasks happen concurrently, leading to a much faster and more efficient dining experience!
Mermaid Diagram
00 sec01 sec02 sec03 sec04 sec05 sec06 sec07 sec08 sec09 secTask A Task A (Thread 1) Task B (Thread 2) Task C (Thread 3) Task B Task C SingleMultiDoing a Task

Q6. Difference between JDK and JVM.

Answer

Here is the arrangement of the statements to correctly differentiate between the Java Development Kit (JDK) and the Java Virtual Machine (JVM).

JDK (Java Development Kit) JVM (Java Virtual Machine)
1) It is required if you need to write Java code, compile it and execute it before deploying it. 2) Each OS platform has a different type of it.
4) It includes Java development tools and Java Runtime Environment. 3) It converts bytecode into machine code that is suitable for a particular type of platform.
6) It contains a Java compiler that generates bytecode. 5) It is a hypothetical (i.e. virtual) computer.
7) It contains a Class loader, Bytecode Verifier, and JIT (Just In Time) compiler.
8) It is required when you already have bytecode and you want to only execute it.
Funny Example: The Chef vs. The Oven 👨‍🍳
  • The JDK is the entire chef's toolkit. It has knives, bowls, a recipe book, and importantly, the oven itself. You need the whole kit if you want to write a new recipe and bake a cake from scratch.
  • The JVM is just the magic oven. If someone hands you a pre-made, ready-to-bake cake mix (bytecode), you only need the oven to bake it. You don't need the whole chef's kit. Every kitchen (OS) has its own brand of magic oven, but they can all bake the same universal cake mix.
Mermaid Diagram

Full Chef's Toolkit

Magic Oven + Libraries

JVM

Libraries

Compiler, etc.


Q7. Draw structure of a Java program and explain it.

Answer

A typical Java program is organized into several key sections.

// 1. Import Statements (Optional)
import java.util.Scanner;

// 2. Class Definition (Required)
class MyClassName {

    // 3. Attributes (Data Members)
    int myVariable;

    // 4. Methods (Member Functions)
    void myMethod() { /* ... */ }

    // 5. main() Method (Required for executable programs)
    public static void main(String args[]) {
        // Program execution starts here
    }
}

Explanation:

  • Import Statements: Used to include classes from other packages.
  • Class Definition: Every Java program must have at least one class, which is a blueprint for objects. The class name usually starts with a capital letter.
  • Attributes: Variables inside the class that hold the state of an object.
  • Methods: Functions inside the class that define the behavior of an object.
  • main() Method: The entry point for any Java application. The JVM starts running the code from here. The file must be saved with the same name as the class that contains the main() method.
Funny Example: Building a Robot 🤖

Think of a Java program as the blueprint for a robot.

  • class Robot: The main blueprint document.
  • import motor.lib;: A note on the blueprint that says, "Use the standard motor parts from this other company."
  • Attributes (int batteryLevel;): A section listing the robot's parts, like its battery level.
  • Methods (void walk();): A section describing what the robot can do, like "walking instructions."
  • main() Method: The big red "START" button on the blueprint that tells you where to begin the assembly process.
Mermaid Diagram

contains

contains

contains

class MyProgram

Attributes (Variables)

Methods (Behaviors)

main() Method (Start Here!)


Q8. Complete the code for command-line arguments.

Answer

Command-line arguments are passed to a program when it's executed and are stored in the String args[] array. The length property gives the number of arguments.

class CommandLineArgDemo {
    public static void main(String args[]) {
        // A: Get the number of arguments
        System.out.println("No of arguments = " + args.length);

        // B: Get the first argument
        System.out.println("First argument is " + args[0]);

        // C: Get the second argument
        System.out.println("Second argument is " + args[1]);

        System.out.print("Other arguments are: ");

        // D: Start the loop from the third argument (index 2)
        for(int i = 2; i < args.length; i++) {
            // E: Print the argument at the current index
            System.out.print(args[i] + " ");
        }
    }
}

Replacements:

  • A: args.length
  • B: args[0]
  • C: args[1]
  • D: 2
  • E: args[i]
Funny Example: Ordering Pizza Toppings 🍕

Running java PizzaShop pepperoni mushroom onions is like shouting your pizza topping order at the command line.

  • args.length is the shopkeeper counting how many toppings you yelled (3).
  • args[0] is the first topping they heard ("pepperoni").
  • args[1] is the second ("mushroom").
  • The for loop is the shopkeeper going through the rest of your order to make sure they got everything else ("onions").
Mermaid Diagram

Command: java MyProgram Hello World 123

args Array

args[0] = 'Hello'

args[1] = 'World'

args[2] = '123'


Q9. Differentiate between Procedural and Object-Oriented Programming.

Answer

Here is a table differentiating Procedural Programming (POP) from Object-Oriented Programming (OOP) based on the provided statements.

Basis of Difference Procedural Programming (POP) Object-Oriented Programming (OOP)
Core Unit The program is implemented as a collection of many functions. The program is implemented as a collection of classes and their objects.
Primary Focus Functions are more important than data. Data is more important than functions.
Data & Function Handling Functions and data are not kept together (no encapsulation). Functions and data are kept together inside a class (encapsulation is used).
Maintainability Debugging and maintenance of code is more difficult. Debugging and maintenance of code is easier.
Example Languages Examples of languages used: C, Pascal. Examples of languages used: C++, Java, C#, Python.
Funny Example: Building a Car 🚗
  • Procedural Programming is like getting a giant box of unsorted car parts and a long list of instructions. "Step 1: Attach wheel to axle. Step 2: Attach other wheel to axle..." You focus on the actions (functions). If something breaks, you have to read the whole instruction manual to figure out where you went wrong.
  • Object-Oriented Programming is like getting pre-built, self-contained modules: an engine object, a chassis object, four wheel objects. Each object knows its own data (e.g., the engine knows its horsepower) and its own functions (the engine knows how to start()). You just connect the objects. If the engine breaks, you only need to debug the engine object.
Mermaid Diagram

OOP

Object 1
Data + Functions

Object 2
Data + Functions

Object 3
Data + Functions

Procedural

Data

Functions

Functions

Functions


Unit 2: Fundamental Programming Structures

Q10. List all the basic datatypes available in Java. Explain any three of them.

Answer

Java has eight primitive data types, which are the fundamental building blocks for data.

List of All Primitive Data Types:

Data Type Size Stores
byte 1 byte Small whole numbers (-128 to 127)
short 2 bytes Medium whole numbers (-32,768 to 32,767)
int 4 bytes Large whole numbers (most common)
long 8 bytes Very large whole numbers
float 4 bytes Numbers with decimal points (6-7 digits)
double 8 bytes Numbers with decimal points (approx. 15 digits)
boolean 1 bit true or false values
char 2 bytes A single character, like 'A'

Explanation of Three Common Data Types:

  1. int (Integer): This is the default choice for whole numbers. It's a good balance of size and range for most everyday counting tasks, like tracking a score or age.
  2. double: This is used for numbers with a fractional part, like prices or measurements. It offers high precision, making it suitable for calculations where accuracy matters.
  3. boolean: This is the simplest type and can only hold one of two values: true or false. It's perfect for tracking conditions, like whether a user is logged in or a light is switched on.
Funny Example: Choosing a Drink Container 🥤

Choosing a data type is like picking a container for a drink.

  • byte: An espresso shot glass. Perfect for a small amount, but useless for a lot.
  • int: A standard coffee mug. Great for most everyday needs.
  • long: A giant, 2-liter soda bottle. Only needed when you're really thirsty for numbers.
  • boolean: A cup that can only hold a sip of "Truth Serum" (true) or "Lying Juice" (false). Nothing else fits.
Mermaid Diagram
🔢 Primitive TypesInteger TypesFloating-Point TypesLogical TypeTextual Typebyteshortintlongfloatdoublebooleanchar

Q11. Complete the for-each loop syntax.

Answer

The for-each loop, also known as the enhanced for loop, is used to easily iterate over all elements of an array or collection. It works on an element-by-element basis, not by index. Its syntax is for(Type variable : array).

public static void main(String[] args) {
    int a[] = {10, 12, 14, 16, 18, 20};

    // The for-each loop
    for (int i : a) { // Corrected line
        System.out.println(i);
    }
}

Replacements:

  • A (Type): int - This must match the data type of the elements in the array.
  • B (Variable): i (or any valid name) - This variable will hold each element of the array during each loop iteration.
  • C (Array): a - This is the array being traversed.
  • E (Element to print): i - This is the variable that holds the current element.
Funny Example: The Sushi Conveyor Belt 🍣

A for-each loop is like a sushi conveyor belt.

  • The array a is the entire belt of sushi plates.
  • for (SushiPlate currentPlate : conveyorBelt) is you saying, "For each sushi plate that passes by on this belt..."
  • System.out.println(currentPlate); is you picking up each plate and eating it.
    You don't care about the plate's position (index); you just process each one as it comes to you.
Mermaid Diagram

1st iteration

2nd iteration

3rd iteration

Array: 🍎, 🍌, 🍒

for-each loop

i = 🍎

i = 🍌

i = 🍒


Q12. Explain parameterized constructor with suitable example. Also, discuss how a parameterized constructor is overloaded with suitable example.

Answer

1. Parameterized Constructor

A parameterized constructor is a constructor that has a specific number of parameters. It's used to provide different initial values to different objects right when they are created.

2. Constructor Overloading

Constructor overloading is a technique of having more than one constructor in a class, each with a different list of parameters. The compiler differentiates them by the number and type of parameters, allowing for flexible object creation.

Combined Example:

class Student {
    int id;
    String name;
    int age;

    // Constructor 1: Takes id and name
    Student(int i, String n) {
        id = i;
        name = n;
    }

    // Constructor 2 (Overloaded): Takes id, name, and age
    Student(int i, String n, int a) {
        id = i;
        name = n;
        age = a;
    }

    void display() {
        System.out.println(id + " " + name + " " + age);
    }

    public static void main(String args[]) {
        Student s1 = new Student(1, "abc");
        Student s2 = new Student(2, "xyz", 22);
        s1.display(); // Output: 1 abc 0
        s2.display(); // Output: 2 xyz 22
    }
}
Funny Example: Creating a Superhero 🦸

Think of constructors as different ways to create a superhero in a video game using the Hero class.

  • Hero hero1 = new Hero("Captain Coder", "Bug Squashing");
    This is the "Quick Start" option. You pick a name and a power, and the game gives you the standard 100 health points. This calls Constructor 1.

  • Hero hero2 = new Hero("The Debugger", "Infinite Patience", 500);
    This is the "Advanced Create-a-Character" screen. You get to customize everything, including starting with a massive 500 health points. This calls the overloaded Constructor 2.

Mermaid Diagram

Hero Class Blueprints

Creating a Hero

new Hero('Captain Coder', 'Bug Squashing')

new Hero('The Debugger', 'Patience', 500)

Constructor(name, power)
health = 100

Overloaded Constructor(name, power, health)

💥 Hero Object Created!


Q14. Explain static data-members and static methods with the help of suitable code.

Answer

The static keyword in Java is used for memory management and signifies that a member belongs to the class itself, rather than to any individual object (instance) of the class.

1. Static Data Members (Class Variables)

A variable declared as static is shared among all objects of that class. It gets memory only once when the class is loaded, making it memory efficient. It's perfect for properties that are common to all objects, like the college name for students.

2. Static Methods

A method declared as static also belongs to the class, not an object. It can be called directly using the class name, without needing to create an object first. A static method can only access static data members directly and cannot use this or super keywords.

Example:

class Student {
    int rollno;
    String name;
    static String college = "CICA"; // Static variable

    // Static method to change the static variable
    static void change() {
        college = "CMPICA";
    }

    Student(int r, String n) {
        rollno = r;
        name = n;
    }

    void display() {
        System.out.println(rollno + " " + name + " " + college);
    }

    public static void main(String args[]) {
        Student.change(); // Calling static method via class name

        Student s1 = new Student(1, "abc");
        Student s2 = new Student(2, "xyz");

        s1.display(); // Output: 1 abc CMPICA
        s2.display(); // Output: 2 xyz CMPICA
    }
}
Funny Example: The School's Announcement System 📢

Think of a Student class.

  • name and rollno are instance variables. Each student has their own unique name and roll number, like their personal backpack.
  • college is a static variable. The name of the college is the same for everyone. It's like a giant sign at the school entrance—there's only one, and it applies to all students.
  • The principal's announcement, changeCollegeName(), is a static method. The principal doesn't need to go to each student individually to tell them the college name has changed. They use the school's central PA system (the static method) to change the name for everyone at once.
Mermaid Diagram

Objects

Student Class

shares

shares

modifies

static String college = 'CICA'

static void change()

Student s1
rollno=1, name='abc'

Student s2
rollno=2, name='xyz'


Q17. Design a Java class Student that demonstrates constructor overloading, use of this keyword, and a method that returns an object.

Answer

This Student class demonstrates all three concepts:

class Student {
    int rollno;
    String name;
    String course;

    // Constructor #1
    Student(int rollno, String name, String course) {
        // `this.rollno` refers to the instance variable
        this.rollno = rollno;
        this.name = name;
        this.course = course;
    }

    // Constructor #2 (Overloading)
    Student(int rollno, String name) {
        // `this(...)` calls another constructor from the same class.
        this(rollno, name, "General"); // Reuses logic from Constructor #1
    }

    // Method that returns an object of this class
    public Student getSelf() {
        // `return this` returns the current object instance.
        return this;
    }

    public void display() {
        System.out.println(rollno + " " + name + " " + course);
    }
}
Funny Example: Cloning Machine 🐑
  • Constructor Overloading: Creating a Student is like using a cloning machine. new Student(101, "Alice", "Java") is the full procedure where you specify everything. new Student(102, "Bob") is the "express" setting, where the machine just assigns a default course ("General").
  • this keyword: this.name = name is the machine's log saying, "The name I was just given (name parameter) should be stamped onto the official name tag of the clone I am currently making (this.name instance variable)." this(...) is the express setting telling the full setting, "Hey, you handle the name and ID, I'll just use a default course."
  • getSelf() method: This method is like a button on the clone that, when pushed, hands you a remote control (return this) that controls that specific clone.
Mermaid Diagram

Student

-int rollno

-String name

-String course

+Student(rollno, name, course)

+Student(rollno, name)

+getSelf() : Student

getSelf() : returns a reference to itself

Student(rollno, name) calls this(rollno, name, 'General')


Unit 3: Inheritance and Polymorphism

Q18. List types of inheritance supported by Java. Discuss syntax of inheritance in Java.

Answer

Inheritance is the process where one class acquires the properties and methods of another class, promoting code reusability. The class that inherits is the subclass (child), and the class being inherited from is the superclass (parent).

Types of Inheritance in Java

Java supports the following types of inheritance:

  1. Single Inheritance: A class extends only one other class.
  2. Multilevel Inheritance: A class extends a subclass, forming a chain (e.g., C extends B, and B extends A).
  3. Hierarchical Inheritance: Multiple classes extend the same single superclass.
  4. Hybrid Inheritance: A combination of two or more types of inheritance.
Multiple Inheritance

Java does not directly support multiple inheritance (one class extending multiple superclasses) to avoid complexity. This can be achieved using interfaces.

Syntax of Inheritance

Inheritance is implemented using the extends keyword.

// Superclass (Parent)
class <base_class_name> {
    // members and methods
}

// Subclass (Child)
class <derived_class_name> extends <base_class_name> {
    // new members and methods can be added
}
Funny Example: Family Traits 👪

Inheritance in Java is just like in a family.

  • Superclass Person: Has properties like name and methods like eat().
  • Subclass Musician: class Musician extends Person means a Musician is a Person. They automatically inherit the name and the ability to eat(). They also add their own unique methods, like playGuitar(). You don't have to re-teach a musician how to eat; they get that for free from their parent class!
Mermaid Diagram

Multilevel Inheritance

Hierarchical Inheritance

Single Inheritance

Superclass
Vehicle

Subclass
Car

Subclass
Bicycle

Sub-Subclass
SportsCar


Q19. Explain effect of access specifiers on inheritance of members of the base class.

Answer

The ability for a subclass to inherit members from its superclass is determined by the access specifier used for those members in the superclass.

Access Specifier Inherited by Subclass? Explanation
public Yes, always Public members are always inherited by all subclasses, no matter where they are.
protected Yes, but limited Protected members are inherited by the immediate next-level subclass only. In a chain like A -> B -> C, a protected member of A is inherited by B, but not by C.
default (none) Yes, within the same package Members with no specifier are inherited only if the subclass is in the same package (folder) as the superclass.
private No, never Private members are never inherited. They are completely hidden and accessible only within their own class.
Funny Example: Family Secrets 🤫

Think of a superclass Parent and a subclass Child.

  • public String lastName: This is the family's last name. It's public knowledge, and the child always inherits it.
  • protected String carKeys: These are the car keys. The child can inherit them, but a random stranger (unrelated class) can't. If the child has their own child (grandchild), they don't automatically get the original keys.
  • String secretCookieRecipe (default): This is the family's secret cookie recipe. The child inherits it as long as they live in the same house (package). If they move out (different package), they lose access.
  • private String embarrassingDiary: This is the parent's personal diary. It's private, and the child never gets to see or inherit it.
Mermaid Diagram

A

✅ Always Inherited

✅ Inherited by Direct Child

✅ Inherited in Same Package

❌ Never Inherited

Subclass

public member

protected member

default member

private member


Q20. List uses of super keyword. Explain use of super keyword to call base class parametrized constructor with the help of an example.

Answer

The super keyword in Java is a reference variable used to refer to the immediate parent class object.

Uses of the super Keyword

There are three primary uses:

  1. To call the constructor of the base class (super(...)).
  2. To access a data-member of the base class (super.variableName).
  3. To call a method of the base class (super.methodName()).

Calling a Base Class Parameterized Constructor

While a subclass doesn't inherit its parent's constructors, it can (and often must) call them using super(...). This is essential for ensuring that the inherited parts of the object are properly initialized by the superclass's logic.

Rule

The call to super(...) must be the very first statement inside the subclass's constructor.

Example:

class SoftwareComponent {
    String componentName;

    // Base class parameterized constructor
    SoftwareComponent(String name) {
        this.componentName = name;
    }
}

class Microservice extends SoftwareComponent {
    String endpoint;

    Microservice(String name, String endpoint) {
        // Calling the parameterized constructor of the base class
        super(name); // This must be the first line

        this.endpoint = endpoint;
    }
}
Funny Example: Building a House 🏠

Imagine you have a Building class (superclass) and a House class (subclass).

  • The Building constructor is like a contractor who only knows how to lay the foundation. The contractor needs to know the location and size: Building(location, size).
  • The House constructor is a specialized builder who adds walls and a roof. But before they can build walls, the foundation must be laid.
  • So, the first thing the House builder does is call the foundation contractor: super(location, size);. This ensures the base is built correctly before adding house-specific parts. If they tried to build the walls first, the whole thing would collapse (compilation error!).
Mermaid Diagram

B

new House(...)

super(...)
Must be 1st!

Initialize House stuff

Building Constructor
Lays foundation


Q21. Explain use of super keyword to call base class method with the help of an example.

Answer

The super keyword can be used to explicitly call a method from the base class, which is especially useful in method overriding. Method overriding is when a subclass provides its own specific implementation for a method that is already defined in its superclass.

By using super.methodName(), the subclass can execute the parent's version of the method and then add its own new functionality.

Example:

class SoftwareComponent {
    void display() {
        System.out.println("This is a software component.");
    }
}

class Microservice extends SoftwareComponent {
    @Override
    void display() {
        super.display(); // Call the parent's display() method first
        System.out.println("Specifically, it's a microservice.");
    }
}
Funny Example: Like Father, Like Son 👨‍👦

A Parent class has a method tellStory() that tells a decent, but boring, story. The Child class extends Parent and wants to tell a better story.

Instead of starting from scratch, the Child's tellStory() method does this:

  1. It says, super.tellStory(); which is like saying, "Dad, you start..."
  2. Then, it adds its own exciting ending: "And then, a dragon appeared!"

This way, the child reuses the parent's work and just adds their own special touch.

Mermaid Diagram

B

super.display()

Parent's display() executes

Parent's part is done

Child's own code executes

Child Object's display() called


Q22. List uses of final keyword. Explain use of final keyword to prevent inheritance.

Answer

The final keyword in Java is used to apply restrictions. In the context of inheritance, it has two primary uses:

  1. To prevent inheritance (Final Class): A class declared as final cannot be extended or subclassed.
  2. To prevent method overriding (Final Method): A method declared as final in a superclass cannot be overridden in any of its subclasses.

Using final to Prevent Inheritance

When a class is declared final, it signifies that its implementation is complete and cannot be modified or extended. Any attempt to create a subclass from a final class will result in a compilation error. This is often done for security and design reasons. For example, the core String class in Java is final.

Example:

// This class is final and cannot be inherited
final class Smartphone {
    void makeCall() { /* ... */ }
}

// This will cause a COMPILE ERROR
class AIPhone extends Smartphone { // ERROR!
    // ...
}
Funny Example: The Secret Recipe 📜

A final class is like a world-famous chef's secret recipe for a sauce. The chef has perfected it and doesn't want anyone else changing it.

By marking the recipe as final, they are saying, "This is it. The one and only. No one is allowed to create a 'version 2' or an 'improved' version of my sauce." Any junior chef who tries to extend the recipe will be immediately fired (compilation error)!

Mermaid Diagram

extends

extends (ERROR!)

class Vehicle

class Car

final class Smartphone

class AIPhone


Q23. Difference between Abstract class and interface.

Answer

Here is the arrangement of the statements differentiating an Abstract Class from an Interface.

Abstract Class Interface
It is a class with one or more abstract methods. It is a collection of constants and abstract methods.
It can have concrete (regular) methods too. It can NOT have concrete methods.
It can have instance variables. It can have only final variables (constants).
It is inherited by a class using extends. It is implemented by a class using implements.
A class can extend only one abstract class. A class can implement many interfaces.
Funny Example: Car Blueprint vs. Driver's License 🚗
  • An abstract class is like a detailed blueprint for a car. It defines what a car is. It can have some parts fully designed (concrete methods, like a standard radio) and some parts left as sketches (abstract methods, like the engine design, which could be gas, electric, etc.). A car company can only extend one main blueprint.
  • An interface is like a driver's license. It defines what a car can do. It's a contract that says you must have methods for steer(), accelerate(), and brake(). It doesn't care how you build the car, only that it can perform these actions. A vehicle (like a Car, Motorcycle, or even a futuristic Hovercraft) can implement multiple licenses, like a driver's license, a pilot's license, and a boating license.
Mermaid Diagram

Interface (can-do)

Abstract Class (is-a)

Blueprint: Car
- Has variables (color)
- Has concrete methods (honk)
- Has abstract methods (drive)

Contract: Drivable
- Has constants (MAX_SPEED)
- Only abstract methods (steer, brake)

class Toyota extends Car

class Tesla implements Drivable


Q24. Arrange the steps to implement runtime polymorphism in the correct order.

Answer

Runtime Polymorphism, also known as Dynamic Method Dispatch, is a process where the call to an overridden method is resolved at runtime rather than compile-time. The correct order of steps to implement it is as follows:

  1. Create an interface with an abstract method. (Defines the contract).
  2. Create three classes which implement the interface and define the abstract method. (Each class provides a unique implementation).
  3. Declare a variable of type interface. (This variable can hold any object that implements the interface).
  4. Create and assign an object of one of the three classes. Use logic to select the class at runtime. (This is the dynamic decision-making part).
  5. Call the method using the variable of interface type. (The JVM decides at runtime which version of the method to execute).
Funny Example: The Universal Remote Control 📺

Runtime Polymorphism is like having a universal remote for your entertainment system.
6. Interface (Controllable): A blueprint for the remote, stating there must be a pressPowerButton() method.
7. Classes (TV, Stereo, GamingConsole): Each device implements the Controllable interface. The TV's pressPowerButton() turns on the screen, the Stereo's turns on the music, and the Console's starts the game.
8. Interface Variable (Controllable currentDevice;): The remote itself.
9. Runtime Logic (if...else...): You decide you want to watch a movie, so you point the remote at the TV (currentDevice = new TV();).
10. Method Call (currentDevice.pressPowerButton();): You press the power button on the remote. The remote is "smart" enough (the JVM) to know it's currently pointed at the TV, so it executes the TV's version of turning on, not the Stereo's.

Mermaid Diagram

JVM decides at runtime

JVM decides at runtime

interface Controllable { turnOn(); }

class TV implements Controllable

class Stereo implements Controllable

Controllable remote = new TV();

remote.turnOn()

Controllable remote = new Stereo();

remote.turnOn()

TV's turnOn() is called

Stereo's turnOn() is called


Q25. Which is the best choice for an interface with one abstract method that will only be used once? Justify your answer.

Answer

In this situation, the best choice would be to use an Anonymous Class.

Justification:

  1. Single-Use and Concise: An anonymous class is a class without a name that is declared and instantiated at the same time. It's designed for a single, one-time use, which perfectly fits the scenario.
  2. Reduces Boilerplate: Instead of creating a whole new .java file for a named class, defining the method, then creating an object of it, an anonymous class combines all these steps into a single, clean expression.
  3. Improves Readability: By defining the implementation right where it's needed, the code becomes more localized and easier to understand. There's no need to hunt for a separate class file that is only used in one place.

Example:

// Create an object of an anonymous class that implements the interface
FingerprintScanner scanner = new FingerprintScanner() {
    @Override
    public void scanFingerprint() {
        System.out.println("Scanning Fingerprint.....");
    }
};
scanner.scanFingerprint();
Funny Example: The Disposable Camera 📸
  • Normal Class: This is like buying a professional, reusable DSLR camera. You have a separate camera body (the class file), a lens, a memory card, etc. It's powerful but bulky if you only want to take one picture.
  • Anonymous Class: This is like a single-use disposable camera. You buy it, take your picture, and you're done. You get the functionality of a camera (implementing the interface) without the hassle of creating a permanent, named object that you'll never use again. It's quick, easy, and leaves no clutter.
Mermaid Diagram

Anonymous Class Approach

Regular Class Approach

Create MyScanner.java file

Implement interface in it

Create object: new MyScanner()

new Scanner() { ... };
(Class definition and object
creation in one step!)

Method is ready to be called


Unit 4: Packages and Wrapper Classes

Q27. Complete the code for implementing an interface.

Answer

When a class implements an interface, it must provide a concrete implementation for all of the interface's abstract methods. By default, methods in an interface are public and abstract. Therefore, the implementing methods in the class must be declared as public.

interface Device {
    String platform = "Android";
    void switchOn();
    void switchOff();
    void reset();
}

class Tablet implements Device { // A = implements
    public void switchOn() { // B = public
        // Some code...
    }

    public void switchOff() { // C = public
        // Some code...
    }

    public void reset() { // D = public, E = void
        // Some code...
    }
}

Replacements:

  • A: implements
  • B: public
  • C: public
  • D: public
  • E: void
Funny Example: The Job Contract 💼

An interface is like a job contract. It lists all the duties you must perform (abstract methods like submitReport(), attendMeeting()).

class Employee implements JobContract is you signing that contract. This means you are legally obligated to provide a real-world implementation for every duty listed. You can't just say "I'll do it"; you have to write down how you'll do it (public void submitReport() { ... }). Also, your work must be visible to your boss, so your methods must be public.

Mermaid Diagram

implements

B

public void switchOn() { ... }

public void switchOff() { ... }

A

void switchOn()

void switchOff()


Q28. Differentiate between primitive data types and their wrapper classes in Java.

Answer

In Java, wrapper classes turn primitive data types into objects. For every primitive type, there is a corresponding wrapper class (e.g., int has Integer, boolean has Boolean).

Here's the main difference:

Feature Primitive Types (int, double) Wrapper Classes (Integer, Double)
Nature Simple, raw values. Not objects. They are objects that contain a primitive value.
Default Value Have a default value (e.g., int is 0). Default value is null.
Methods Have no methods. They are just values. Provide helpful utility methods (e.g., Integer.parseInt()).
Collections Cannot be stored in collections like ArrayList. Required for collections (e.g., ArrayList<Integer>).

Java handles the conversion automatically through autoboxing (primitive to wrapper) and unboxing (wrapper to primitive).

Funny Example: Action Figure vs. Person 🧍‍♂️
  • A primitive int is like a plastic toy soldier. It represents a soldier, it's lightweight, and you can have a million of them. But it can't do anything on its own. It has no brain or skills (no methods).
  • An Integer wrapper object is like a real-life secret agent. He is a full-fledged person (an object) who happens to have a number, his agent ID (the wrapped int value). But because he's a person, he also has built-in skills and gadgets (methods like .toString() and .compareTo()). You can also add him to a team of other agents (ArrayList<Integer>).
Mermaid Diagram

Wrappers

Primitives

Autoboxing

Unboxing

int i = 5;
Just a value

Integer obj = 5;
An object with
value & methods

✅ Can use in ArrayList

❌ Cannot use in ArrayList


Q29. Do you think using wildcard imports is better than single-class imports? Support your answer with reasons.

Answer

For writing clean, maintainable, and professional code, single-class imports (import java.util.Scanner;) are considered better than wildcard imports (import java.util.*;).

Here's a comparison of the reasons:

Single-Class Imports (import package.name.Class;)

  • Clarity and Readability: It is immediately obvious which specific classes your file depends on just by looking at the top of the code. This makes the code much easier for others (and your future self) to understand.
  • No Name Conflicts: This approach prevents ambiguity. If two different packages have a class with the same name (e.g., java.util.List and java.awt.List), a single-class import makes it clear which one you intend to use. A wildcard import could lead to a compilation error in such cases.

Wildcard Imports (import package.name.*;)

  • Convenience: The only real advantage is that they can be quicker to type if you are using many classes from the same package. It can also make the import section of your file shorter.

Conclusion: While wildcard imports offer minor convenience, single-class imports are superior because they promote code that is explicit, readable, and less prone to errors. In professional and academic settings, clarity and maintainability are far more important than saving a few keystrokes.

Funny Example: Grocery Shopping 🛒
  • Single-Class Import is like having a specific grocery list: "Milk, Bread, Eggs." You know exactly what you need, and you go get it. There's no confusion.
  • Wildcard Import is like going to the store and shouting, "I'll take one of everything from the dairy aisle!" It's easy to say, but you might end up with three different kinds of milk and some yogurt you didn't want (name conflicts and unnecessary dependencies), and the store manager (the compiler) might get confused.
Mermaid Diagram

import java.util.*;

⚡ Convenient

❓ Ambiguous

⚠️ Potential Name Clashes

import java.util.Scanner;

✅ Clear & Specific

✅ Avoids Name Clashes

✅ Easy to Maintain


Q30. Develop a Java program to illustrate creating a package and using it with CLASSPATH setting.

Answer

Creating and using a package involves organizing your .java files into directories, compiling them correctly, and then telling the Java Virtual Machine (JVM) where to find them using the CLASSPATH.

Step 1: Create the Package Structure and Source File

First, create a directory structure. Let's make a root folder named project and inside it, a package folder named mytools.

project/
└── mytools/
    └── Calculator.java

Inside Calculator.java, write the following code, declaring it as part of the mytools package.

// Save as project/mytools/Calculator.java
package mytools;

public class Calculator {
    public int add(int a, int b) {
        return a + b;
    }
}

Step 2: Compile the Packaged Class

Navigate to the project directory in your command line and run the compiler with the -d . flag. This flag tells the compiler to create the package directory structure in the current location (.).

# Navigate to the root folder
cd project

# Compile the .java file
javac -d . mytools/Calculator.java 

This command will create project/mytools/Calculator.class.

Step 3: Create a Main Program to Use the Package

Now, create a new file, MainApp.java, in the project root folder. This program will import and use our Calculator class.

project/
├── mytools/
│   ├── Calculator.java
│   └── Calculator.class  <-- (This was created by the compiler)
└── MainApp.java
// Save as project/MainApp.java
import mytools.Calculator; // Import our custom class

public class MainApp {
    public static void main(String[] args) {
        Calculator calc = new Calculator();
        int result = calc.add(10, 25);
        System.out.println("The result is: " + result);
    }
}

Step 4: Compile and Run with CLASSPATH

The CLASSPATH is an environment variable that tells the Java compiler and JVM where to find the .class files for user-defined packages. By default, it includes the current directory (.).

Stay in the project directory and compile MainApp.java. The compiler will look in the current directory, find the mytools folder, and locate Calculator.class.

# Still in the project/ directory
javac MainApp.java

# Run the main application, referring to it by its class name
java MainApp 

Output:

The result is: 35

This works because the project folder (our current location, .) is the root of our classpath, and the JVM can correctly find mytools/Calculator.class from there.

Funny Example: The Custom Toolbox 🔧
  • Package (mytools): A special toolbox you built and labeled "Math Tools."
  • Class (Calculator.class): A unique wrench inside that toolbox called the "Adder Wrench."
  • CLASSPATH: This is your brain's memory of where you keep your toolboxes. When your main project needs the "Adder Wrench" (Calculator), the JVM (your brain) checks the CLASSPATH and says, "Ah, I know! It's in the 'Math Tools' toolbox, which is right here in my garage (the current directory)." If you had put the toolbox in the shed, you'd need to update your memory (CLASSPATH) to include the shed.
Mermaid Diagram

Step 3, 4, 5: Use Package

Step 1 & 2: Create & Compile Package

Found via CLASSPATH

📁 root/mytools/Calculator.java
package mytools;

javac -d . mytools/Calculator.java

✅ Creates:
📁 root/mytools/Calculator.class

📁 root/MainApp.java
import mytools.*;

javac MainApp.java
Compiler uses CLASSPATH to find .class file

java MainApp
JVM uses CLASSPATH to run

🎉 Output: The result is: 35


🔑 Glossary of Key Terms

  • Abstract Class: A class that cannot be instantiated and may contain abstract (unimplemented) methods. A class can only extend one abstract class. [See Q23](#q23-difference-between-abstract-class-and-interface)
  • Anonymous Class: A class without a name, created for a single, one-time use, typically to implement an interface or extend a class on the fly. [See Q25](#q25-which-is-the-best-choice-for-an-interface-with-one-abstract-method-that-will-only-be-used-once)
  • Bytecode: The platform-independent, intermediate code generated by the Java compiler from .java source files. It is stored in .class files. [See Q1](#q1-why-are-java-programs-platform-independent)
  • CLASSPATH: An environment variable that tells the Java compiler and JVM where to find user-defined classes and packages. [See Q30](#q30-develop-a-java-program-to-illustrate-creating-a-package-and-using-it-with-classpath-setting)
  • Constructor: A special method used to initialize a newly created object. Its name must be the same as the class name and it has no return type. [See Q12](#q12-explain-parameterized-constructor-with-suitable-example-also-discuss-how-a-parameterized-constructor-is-overloaded-with-suitable-example)
  • extends: The keyword used in a class declaration to specify its superclass, thereby achieving inheritance. [See Q18](#q18-list-types-of-inheritance-supported-by-java-discuss-syntax-of-inheritance-in-java)
  • final: A keyword used to apply restrictions. A final class cannot be inherited, and a final method cannot be overridden. [See Q22](#q22-list-uses-of-final-keyword-explain-use-of-final-keyword-to-prevent-inheritance)
  • implements: The keyword used in a class declaration to specify one or more interfaces that the class will implement. [See Q27](#q27-complete-the-code-for-implementing-an-interface)
  • Inheritance: The process where one class (the subclass) acquires the properties and methods of another class (the superclass). [See Q18](#q18-list-types-of-inheritance-supported-by-java-discuss-syntax-of-inheritance-in-java)
  • Interface: A collection of abstract methods and constants. A class can implement multiple interfaces to achieve a form of multiple inheritance. [See Q23](#q23-difference-between-abstract-class-and-interface)
  • JDK (Java Development Kit): A software development kit required to develop Java applications. It includes the JRE, a compiler (javac), a debugger, and other tools. [See Q6](#q6-difference-between-jdk-and-jvm)
  • JIT (Just-In-Time) Compiler: A part of the JVM that improves performance by compiling frequently executed bytecode ("hot code") into native machine code at runtime. [See Q3](#q3-explain-just-in-time-compilation)
  • JVM (Java Virtual Machine): A virtual computer that executes Java bytecode. It is responsible for making Java platform-independent. [See Q1](#q1-why-are-java-programs-platform-independent)
  • Multithreading: The ability of a program to execute multiple parts of its code (threads) concurrently, improving performance and responsiveness. [See Q5](#q5-discuss-multithreading-capability-of-java-programs)
  • Package: A way to group related classes and interfaces, similar to a folder in a file system. Used to avoid name conflicts and organize code. [See Q30](#q30-develop-a-java-program-to-illustrate-creating-a-package-and-using-it-with-classpath-setting)
  • Polymorphism (Runtime): The ability of an object to take on many forms. Runtime polymorphism allows the JVM to decide at runtime which method to execute, based on the actual object type. Also known as Dynamic Method Dispatch. [See Q24](#q24-arrange-the-steps-to-implement-runtime-polymorphism-in-the-correct-order)
  • static: A keyword indicating that a member belongs to the class itself, rather than to an instance of the class. Static members are shared among all objects of the class. [See Q14](#q14-explain-static-data-members-and-static-methods-with-the-help-of-suitable-code)
  • super: A keyword used to refer to the immediate parent class. It can be used to call the parent's constructor or access its members. [See Q20](#q20-list-uses-of-super-keyword-explain-use-of-super-keyword-to-call-base-class-parametrized-constructor-with-the-help-of-an-example)
  • this: A keyword that is a reference to the current object. It can be used to refer to instance variables, call methods, or invoke another constructor of the same class. [See Q17](#q17-design-a-java-class-student-that-demonstrates-constructor-overloading-use-of-this-keyword-and-a-method-that-returns-an-object)
  • Wrapper Class: A class that provides a way to use primitive data types (like int, double) as objects (e.g., Integer, Double). [See Q28](#q28-differentiate-between-primitive-data-types-and-their-wrapper-classes-in-java)